﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using MDK;
using System.Windows.Forms;
using MDK.Physics;
using ZedGraph;
using Tao;
using Tao.OpenGl;
using Tao.FreeGlut;
using Tao.Platform.Windows;

namespace WPDuality
{
    public class WPDuality : GraphicPrimitive
    {
        public override ExperimentAbout GetAbout()
        {
            return new ExperimentAbout("WPDuality", "Зондирование протона",
                "Зондирование протона электронами с различной длиной волны, с целью изучения внутреней структуры протона.\r\n" +
                "E - энергая частицы. \r\n" +
                "M - масса частицы.\r\nРасчет идет по формуле: lamda = h/(sqrt(E^2 - M^2))\r\nМасса электрона - 9,1");
        }
        #region Конструкторы
        public WPDuality()
            : base(0, 0, new Size())
        {
            this.Needs = ExperimentNeeds.OpenGL;
            AddParametersToTemplate();
        }

        public WPDuality(int Left, int Top, Size Size)
            : base(Left, Top, Size)
        {
            this.Needs = ExperimentNeeds.OpenGL; // нужды

            // передаём размеры
            this.Left = Left;
            this.Top = Top;

            this.Size = Size;

            //создаём список по умолчанию
            AddParametersToTemplate();
        }
        #endregion

        #region Методы взаимодействия с главным модулем
        private void AddParametersToTemplate()
        {
            ParameterListTemplate = new ParameterList();
            ParameterListTemplate.Add("Энергия электрона", "E", 10);
            //ParameterListTemplate.Add("Масса", "M", 2);
        }
        double E, M = 9.1;
        public override void SetParameters(ParameterList pList)
        {
            E = pList["E"];
            if (E < M)
            {
                MessageBox.Show("E должно быть больше M","Ошибка!");
                E = 10;
            }
            //M = pList["M"];
        }


        public override ParameterList GetParameters()
        {
            ParameterList RetList = ParameterListTemplate;

            //todo: в RetList заносим "внутренние" переменные

            return RetList;
        }

        public override PointPairList GetResults()
        {
            // todo: возвращаем результаты для статистики
            return new PointPairList();
        }

        public override void GL_camera(double[] cameraPos, double[] targetPos, double[] rotateA)
        {
            Glu.gluLookAt(cameraPos[0], cameraPos[1], cameraPos[2], targetPos[0], targetPos[1], targetPos[2],
                0, 1, 0); // еденичный вектор смотрит вверх
            //Gl.glTranslatef((float)targetPos[0], (float)targetPos[1], (float)targetPos[2]);
            Gl.glScaled(targetPos[3], targetPos[3], targetPos[3]);
            Gl.glRotated(-rotateA[0], 1, 0, 0);
            Gl.glRotated(rotateA[1], 0, 1, 0);
            Gl.glRotated(-rotateA[2], 0, 0, 1);

        }

        public override void GL_init(int w, int h)
        {

            Gl.glClearColor(0, 0, 0, 1);


            Gl.glMatrixMode(Tao.OpenGl.Gl.GL_PROJECTION);
            Gl.glLoadIdentity();
            Gl.glViewport(0, 0, w, h);
            //Glu.gluPerspective(45, w / h, 0.1, 500);
            Gl.glOrtho(-w / 2, w / 2, -h / 2, h / 2, -1000, 1000);

            Gl.glMatrixMode(Tao.OpenGl.Gl.GL_MODELVIEW);
            Gl.glLoadIdentity();

            Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT);        // Clear Screen And Depth Buffer
            Gl.glLoadIdentity();

            Gl.glEnable(Gl.GL_DEPTH_TEST);
        }


        /// <summary>
        /// Метод рисования
        /// </summary>
        /// <param name="e"></param>
        public override void Draw(System.Windows.Forms.PaintEventArgs e)
        {
            double lamda = 1/Math.Sqrt(E*E - M*M);
            Gl.glRotatef(90, 0, 0, 1);
            Gl.glTranslatef(-200, 0, 0);
            Glu.GLUquadric quadric = Glu.gluNewQuadric();
            Gl.glLineWidth(1);
            Gl.glPushMatrix();
            Gl.glColor3d(1, 0.3, 0.3);
            Glu.gluQuadricDrawStyle(quadric, Glu.GLU_LINE);
            Glu.gluSphere(quadric, 60, 24, 24);
            Gl.glPopMatrix();

            Gl.glPushMatrix();
            Gl.glTranslated(28, 28, 0);
            Gl.glColor3d(0.3, 0.3, 0.678);
            Glu.gluQuadricDrawStyle(quadric, Glu.GLU_FILL);
            Glu.gluSphere(quadric, 19, 24, 24);
            Gl.glPopMatrix();

            Gl.glPushMatrix();
            Gl.glTranslated(-28, 28, 0);
            Gl.glColor3d(0.3, 0.3, 0.678);
            Glu.gluQuadricDrawStyle(quadric, Glu.GLU_FILL);
            Glu.gluSphere(quadric, 19, 24, 24);
            Gl.glPopMatrix();

            Gl.glPushMatrix();
            Gl.glTranslated(0, -38, 0);
            Gl.glColor3d(0.3, 0.678, 0.3);
            Glu.gluQuadricDrawStyle(quadric, Glu.GLU_FILL);
            Glu.gluSphere(quadric, 19, 24, 24);
            Gl.glPopMatrix();

            Gl.glLineWidth(2.8f);
            Gl.glColor3d(1, 1, 1);
            Gl.glPushMatrix();
            Gl.glTranslatef(6*90 - 35, 0, 0);
            Gl.glBegin(Gl.GL_LINE_STRIP);
            for (double i = 0; i < 6; i+=0.1*lamda)
            {
                Gl.glVertex2d(-90*i, 90*Math.Sin(i/lamda));
            }
            Gl.glEnd();
            
            Gl.glColor3d(0.3, 0.6, 0.3);
            Gl.glBegin(Gl.GL_LINES);
                Gl.glVertex2d(80, 100);
                Gl.glVertex2d(0, 0);
                Gl.glVertex2d(10, -120);
                Gl.glVertex2d(0, 0); 
            Gl.glEnd();
            
            Gl.glPopMatrix();

            /*Gl.glPushMatrix();
            Gl.glTranslatef(-32 * 90 / 2, 0, 0);
            Gl.glBegin(Gl.GL_LINE);
            Gl.glVertex2d(10, 50);
            Gl.glVertex2d(0, 0);
            Gl.glEnd();*/

            Gl.glPopMatrix();
            Gl.glFlush();
            Glu.gluDeleteQuadric(quadric);
        }


        #endregion
    }

}
